function MVVM(options) {
    //给实例(vm)增加一个$options的属性,并且把传递过来的配置进行赋值
    this.$options = options;
    //奖配置中的data属性赋值给实例上新增的(_data),并且把data数据进行暂存
    var data = this._data = this.$options.data;
    //暂存this(确保this指向)
    var me = this;

    //通过Object.keys取出data中所有的属性名,遍历所有的属性名,调用_proxy方法(实现数据代理)
    Object.keys(data).forEach(function(key) {
        me._proxy(key);
    });

    //遍历data中所有层次的属性,为每一个属性增加get和set方法
    observe(data, this);

    //解析模版
    this.$compile = new Compile(options.el || document.body, this)
}

MVVM.prototype = {
    $watch: function(key, cb, options) {
        new Watcher(this, key, cb);
    },

    _proxy: function(key) {//实现数据代理
        //暂存this 确保this指向正确 这里的this还是MVVM的实例(vm)
        var me = this;
        //通过Object.defineProperty为vm实例增加所有的data中拥有的属性的属性名, 并且为该属性添加gat和set方法
        Object.defineProperty(me, key, {
            configurable: false,//当前新增的属性不可重新定义或删除
            enumerable: true,//可以枚举
            get: function proxyGetter() {//当使用vm.xxx的时候会触发当前方法
                //实现了vm代理data中数据的读操作
                return me._data[key];
            },
            set: function proxySetter(newVal) {//当使用vm.xxx=xxx的时候会触发当前方法
                //实现了vm代理data中数据的写操作
                me._data[key] = newVal;
            }
        });
    }
};
